package com.example.app;

import android.content.Context;
import android.util.Log;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import java.util.Timer;
import java.util.TimerTask;

public class MqttUtil {
    private static final String TAG = "MqttUtil";

    // MQTT服务器配置
    private static final String SERVER_URI = "tcp://192.168.0.1";
    private static final String TOPIC = "/map";

    // 重连配置
    private static final long RECONNECT_DELAY_MS = 5000; // 5秒重连间隔

    private Context context;
    private MqttClient mqttClient;
    private MqttConnectOptions connectOptions;
    private Timer reconnectTimer;
    private volatile boolean isConnected = false;
    private String clientId;

    // 连接状态监听器
    private MqttConnectionListener connectionListener;

    public interface MqttConnectionListener {
        void onMqttConnected();
        void onMqttDisconnected();
        void onMqttMessageReceived(String topic, String message);
        void onMqttError(String error);
    }

    // 私有构造函数
    private MqttUtil(Context context) {
        this.context = context.getApplicationContext();
        this.clientId = "AndroidClient_" + System.currentTimeMillis();
        initMqtt();
    }

    // 使用静态内部类实现单例模式（Holder方式）
    private static class SingletonHolder {
        private static MqttUtil instance;

        public static synchronized MqttUtil getInstance(Context context) {
            if (instance == null) {
                instance = new MqttUtil(context);
            }
            return instance;
        }
    }

    /**
     * 获取MqttUtil单例实例
     * @param context 上下文对象
     * @return MqttUtil实例
     */
    public static MqttUtil getInstance(Context context) {
        return SingletonHolder.getInstance(context);
    }

    private void initMqtt() {
        try {
            // 初始化MQTT客户端
            mqttClient = new MqttClient(SERVER_URI, clientId, new MemoryPersistence());

            // 配置连接选项
            connectOptions = new MqttConnectOptions();
            connectOptions.setCleanSession(true);
            connectOptions.setAutomaticReconnect(false); // 我们手动实现重连逻辑
            connectOptions.setConnectionTimeout(10);
            connectOptions.setKeepAliveInterval(20);

            // 设置回调
            mqttClient.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable cause) {
                    isConnected = false;
                    Log.e(TAG, "Connection lost: " + cause.getMessage());
                    if (connectionListener != null) {
                        connectionListener.onMqttDisconnected();
                    }
                    scheduleReconnect();
                }

                @Override
                public void messageArrived(String topic, MqttMessage message) throws Exception {
                    String payload = new String(message.getPayload());
                    Log.d(TAG, "Message arrived: " + topic + " - " + payload);
                    if (connectionListener != null) {
                        connectionListener.onMqttMessageReceived(topic, payload);
                    }
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {
                    Log.d(TAG, "Delivery complete");
                }
            });

        } catch (MqttException e) {
            Log.e(TAG, "Error initializing MQTT: " + e.getMessage());
            if (connectionListener != null) {
                connectionListener.onMqttError(e.getMessage());
            }
        }
    }

    public void connect() {
        if (isConnected) {
            Log.d(TAG, "Already connected");
            return;
        }

        new Thread(() -> {
            try {
                Log.d(TAG, "Connecting to MQTT server...");
                mqttClient.connect(connectOptions);
                
                isConnected = true;
                Log.d(TAG, "Connected to MQTT server");

                // 取消重连定时器
                cancelReconnectTimer();

                try {
                    // 连接成功后订阅主题
                    mqttClient.subscribe(TOPIC, 1);

                    // 发布主题消息
                    publishMessage(TOPIC, "Connected from Android client");
                } catch (MqttException e) {
                    Log.e(TAG, "Error after connection: " + e.getMessage());
                }

                if (connectionListener != null) {
                    connectionListener.onMqttConnected();
                }
            } catch (MqttException e) {
                isConnected = false;
                Log.i(TAG, "Failed to connect: " + e.getMessage());

                if (connectionListener != null) {
                    connectionListener.onMqttError(e.getMessage());
                }

                // 安排重连
                scheduleReconnect();
            }
        }).start();
    }

    public void disconnect() {
        cancelReconnectTimer();

        if (mqttClient != null && mqttClient.isConnected()) {
            try {
                mqttClient.disconnect();
                isConnected = false;
                Log.d(TAG, "Disconnected from MQTT server");
            } catch (MqttException e) {
                Log.e(TAG, "Error disconnecting: " + e.getMessage());
            }
        }
    }

    public void publishMessage(String topic, String message) {
        if (!isConnected) {
            Log.e(TAG, "Not connected, cannot publish message");
            return;
        }

        try {
            MqttMessage mqttMessage = new MqttMessage(message.getBytes());
            mqttMessage.setQos(1);
            mqttClient.publish(topic, mqttMessage);
            Log.d(TAG, "Message published to " + topic);
        } catch (MqttException e) {
            Log.e(TAG, "Error publishing message: " + e.getMessage());
        }
    }

    private void scheduleReconnect() {
        cancelReconnectTimer();

        reconnectTimer = new Timer();
        reconnectTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                Log.d(TAG, "Attempting to reconnect...");
                connect();
            }
        }, RECONNECT_DELAY_MS);
    }

    private void cancelReconnectTimer() {
        if (reconnectTimer != null) {
            reconnectTimer.cancel();
            reconnectTimer = null;
        }
    }

    public boolean isConnected() {
        return isConnected;
    }

    public void setConnectionListener(MqttConnectionListener listener) {
        this.connectionListener = listener;
    }

    public void destroy() {
        disconnect();
        try {
            if (mqttClient != null) {
                mqttClient.close();
            }
        } catch (MqttException e) {
            Log.e(TAG, "Error closing MQTT client: " + e.getMessage());
        }
    }

    /**
     * 重置单例实例（主要用于测试或需要重新初始化的情况）
     */
    public static void resetInstance() {
        synchronized (SingletonHolder.class) {
            SingletonHolder.instance = null;
        }
    }
}